﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SourFruit.player;


namespace SourFruit.menu
{
    class MainMenuWindow : MenuWindow
    {
        public String[] mainMenuTitles;
        public String[] levelTitles;
        public String[] configMenuTitles;
        public String[] keyConfigMenuTitles;
        public String[] soundConfigMenuTitles;


        private enum MainMenu { NewGame = 0, Config, Quit }
        private enum Levels { Level1 = 0,  Level2, Level3, Back }
        private enum ConfigMenu { KeyConfig = 0, SoundConfig, Back }
        private enum KeyConfigMenu { Up = 0, Down, Right, Left, Jump, Back }
        private enum MenuState {Main=0, Level, Config,Key,Sound}
        private enum SoundConfigMenu {ToggleSoundOnOff=0, Back}
        
        /// <summary>
        /// Highlighted menu item.
        /// </summary>
        private MainMenu menu;
        private Levels level;
        private ConfigMenu config;
        private KeyConfigMenu keys;
        private SoundConfigMenu sound;
        private MenuState state;

        public MainMenuWindow(String newgame, String conf, String quit, String keyconf, String soundconf, String back)
        {
            menu                  = MainMenu.NewGame;
            config                = ConfigMenu.KeyConfig;
            mainMenuTitles        = new String[3] { newgame, conf, quit };
            levelTitles           = new String[4] { "1", "2" , "3", "Back" };
            configMenuTitles      = new String[3] { keyconf, soundconf, back };
            keyConfigMenuTitles   = new String[6] { "Up", "Down", "Right", "Left", "Jump", "Back"};
            soundConfigMenuTitles = new String[2] { "Toggle Sound On/Off", "Back" };
        }


        /// <summary>  
        /// Handles the informing the receivers that the players position has changed.  
        /// </summary>  
        /// <param name="sender">The sender of the event.</param>  
        /// <param name="e">The EventArgs of the event.</param>  
        public delegate void Menu(Boolean menuOpen, String[] menuTitles, int highLighted);
        public event Menu MenuChanged;
        /// <summary>
        /// Creates the playable entity. 
        /// </summary>        

        /// <summary>  
        /// Handles the informing the receivers that the players position has changed.  
        /// </summary>  
        /// <param name="sender">The sender of the event.</param>  
        /// <param name="e">The EventArgs of the event.</param>  
        public delegate void LoadLevel(int level);
        public event LoadLevel LoadLevelEvent;        

        /// <summary>  
        /// Handles the informing the receivers that the players position has changed.  
        /// </summary>  
        /// <param name="sender">The sender of the event.</param>  
        /// <param name="e">The EventArgs of the event.</param>  
        public delegate void Quit();
        public event Quit QuitCalled;

        /// <summary>  
        /// Handles the informing the receivers that the players position has changed.  
        /// </summary>  
        /// <param name="sender">The sender of the event.</param>  
        /// <param name="e">The EventArgs of the event.</param>  
        public delegate void GameInput(InputActions input);
        public event GameInput ChangeGameInput;
        
        
        public void GoUP()
        {
            switch (state)
            {
                case MenuState.Main:
                    switch (menu)
                    {
                        case MainMenu.NewGame:
                            menu = MainMenu.Quit;
                            break;
                        default:
                            menu -= 1;
                            break;
                    }
                    break;
                case MenuState.Level:
                    switch (level)
                            {
                        case Levels.Level1:
                            level = Levels.Back;
                            break;
                        default:
                            level -= 1;
                            break;
                    }
                    break;
                case MenuState.Config:
                    switch (config)
                    {
                        case ConfigMenu.KeyConfig:
                            config = ConfigMenu.Back; 
                            break;                        
                        default:
                            config -= 1;
                            break;
                    }
                    break;
                case MenuState.Key:
                    switch (keys)
                    {
                        case KeyConfigMenu.Up:
                            keys = KeyConfigMenu.Back;
                            break;
                        default:
                            keys -= 1;
                            break;
                    }
                    break;
                case MenuState.Sound:
                    switch (sound)
                    {
                        case SoundConfigMenu.ToggleSoundOnOff:
                            sound = SoundConfigMenu.Back;
                            break;
                        default:
                            sound -= 1;
                            break;
                    }
                    break;
            }
            CreateEventMenuChanged(true);
        }

        public void GoDOWN()
        {
            switch (state)
            {
                case MenuState.Main:
                    switch (menu)
                    {
                        case MainMenu.Quit:
                            menu = MainMenu.NewGame;                            
                            break;
                        default:
                            menu += 1;
                            break;
                    }
                    break;
                case MenuState.Level:
                    switch (level)
                    {
                        case Levels.Back:
                            level = Levels.Level1;
                            break;
                        default:
                            level += 1;
                            break;
                    }
                    break;
                case MenuState.Config:
                    switch (config)
                    {
                        case ConfigMenu.Back:
                            config = ConfigMenu.KeyConfig;
                            break;
                        default:
                            config += 1; 
                            break;
                    }
                    break;

                case MenuState.Key:
                    switch (keys)
                    {                        
                        case KeyConfigMenu.Back:
                            keys = KeyConfigMenu.Up;
                            break;
                        default:
                            keys += 1;
                            break;
                    }
                    break;
                case MenuState.Sound:
                    switch (sound)
                    {
                        case SoundConfigMenu.Back:
                            sound = SoundConfigMenu.ToggleSoundOnOff;
                            break;
                        default:
                            sound += 1;
                            break;
                    }
                    break;
            }
            CreateEventMenuChanged(true);
        }


        public Boolean Select()
        {
            Boolean menuOpen = true;
            switch (state)
            {
                case MenuState.Main:
                    switch (menu)
                    {
                        case MainMenu.NewGame:
                            CreateEventMenuChanged(false);
                            state = MenuState.Level;
                            break;
                        case MainMenu.Config:
                            CreateEventMenuChanged(true);
                            state = MenuState.Config;
                            break;
                        case MainMenu.Quit:
                            CreateEventQuit();
                            break;
                    }
                    break;
                case MenuState.Level:
                    switch (level)
                    {
                        case Levels.Back:
                            CreateEventMenuChanged(true);
                            state = MenuState.Main;
                            menuOpen = true;
                            break;
                        default: 
                            CreateEventLoadLevel((int)level);
                            CreateEventMenuChanged(false);
                            state = MenuState.Main;
                            menuOpen = false;
                            break;
                    }                    
                    break;
                case MenuState.Config:
                    switch (config)
                    {
                        case ConfigMenu.KeyConfig:
                            CreateEventMenuChanged(true);
                            state = MenuState.Key;
                            break;
                        case ConfigMenu.SoundConfig:
                            CreateEventMenuChanged(true);
                            state = MenuState.Sound;
                            break;
                        default:
                            CreateEventMenuChanged(true);
                            state = MenuState.Main;
                            break;
                    }
                    break;
                    //TODO
                case MenuState.Key:
                    switch (keys)
                    {
                        case KeyConfigMenu.Up:
                            CreateEventChangeGameInput(InputActions.up);
                            break;
                        case KeyConfigMenu.Down:
                            CreateEventChangeGameInput(InputActions.down);
                            break;
                        case KeyConfigMenu.Right:
                            CreateEventChangeGameInput(InputActions.right);
                            break;
                        case KeyConfigMenu.Left:
                            CreateEventChangeGameInput(InputActions.left);
                            break;
                        case KeyConfigMenu.Jump:
                            CreateEventChangeGameInput(InputActions.jump);
                            break;
                        case KeyConfigMenu.Back:
                            CreateEventMenuChanged(true);
                            state = MenuState.Config;
                            break;
                    }
                    break;
                case MenuState.Sound:
                    switch (sound)
                    {
                        case SoundConfigMenu.ToggleSoundOnOff:
                            break;
                        case SoundConfigMenu.Back:
                            CreateEventMenuChanged(true);
                            state = MenuState.Config;
                            break;
                    }
                    break;
            }
            return menuOpen;
        }

        public void CreateEventChangeGameInput(InputActions input)
        {
            if (ChangeGameInput != null)
            {
                ChangeGameInput(input);
            }
        }

        public void CreateEventQuit()
        {
            if (QuitCalled != null)
            {
                QuitCalled();
            }
        }

        public void CreateEventLoadLevel(int level)
        {
            if (LoadLevelEvent != null)
            {
                LoadLevelEvent(level);
            }
        }

        public void CreateEventMenuChanged(Boolean menuOpen)
        {
            if (MenuChanged != null)
            {
                switch (state)
                {
                    case MenuState.Main:
                        MenuChanged( menuOpen, mainMenuTitles, (int)menu);
                        break;
                    case MenuState.Level:
                        MenuChanged( menuOpen, levelTitles, (int)level);
                        break;
                    case MenuState.Config:
                        MenuChanged( menuOpen, configMenuTitles, (int)config);
                        break;
                    case MenuState.Key:
                        MenuChanged(menuOpen, keyConfigMenuTitles, (int)keys);
                        break;
                    case MenuState.Sound:
                        MenuChanged(menuOpen, soundConfigMenuTitles, (int)sound);
                        break;
                }
            }
        }
    }
}
